// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	2/22/2015 1:43:48 PM				
// -----------------------------

#include "GraphicsManager.h"

#include "Engine.h"
#include "StateManager.h"
#include "TextureManager.h"
#include "ShaderManager.h"

#include "PlatformProvider.h"

#include "IWindow.h"
#include "IGraphicsDevice.h"
#include "IMutex.h"

#include "SpriteBatch.h"

namespace Flow
{

	GraphicsManager::GraphicsManager()
		: m_lpGraphicsDevice(nullptr)
		, m_lpGraphicsMutex(nullptr)
		, m_lpTextures(nullptr)
		, m_lpShaders(nullptr)
		, m_lpSpriteBatch(nullptr)
	{
	}

	GraphicsManager::~GraphicsManager()
	{
		SpriteBatch::UnloadShaders();

		delete m_lpSpriteBatch;
		delete m_lpTextures;
		delete m_lpShaders;

		SafeReleaseInterface(&m_lpGraphicsMutex);
		SafeReleaseInterface(&m_lpGraphicsDevice);
	}

	Bool GraphicsManager::Initialize(IWindow* lpWindow)
	{
		// Create the Graphics Device Interface
		m_lpGraphicsDevice = PlatformProvider::QueryInterface<IGraphicsDevice>("GraphicsDevice");
		ASSERT(m_lpGraphicsDevice);
		if (!m_lpGraphicsDevice)
			return false;

		// Initialize the Graphics Device
		if (!m_lpGraphicsDevice->Initialize(lpWindow))
			return false;

		// Create the Mutex
		m_lpGraphicsMutex = PlatformProvider::QueryInterface<IMutex>("Mutex");
		ASSERT(m_lpGraphicsMutex);
		if (!m_lpGraphicsMutex)
			return false;

		// Create the Texture Manager
		m_lpTextures = new TextureManager(m_lpGraphicsDevice, m_lpGraphicsMutex);
		ASSERT(m_lpTextures);
		if (!m_lpTextures)
			return false;

		// Create the Shader Manager
		m_lpShaders = new ShaderManager(m_lpGraphicsDevice, m_lpGraphicsMutex);
		ASSERT(m_lpShaders);
		if (!m_lpShaders)
			return false;

		// Create the Sprite Batch
		m_lpSpriteBatch = new SpriteBatch();
		ASSERT(m_lpSpriteBatch);
		if (!m_lpSpriteBatch->Initialize())
			return false;

		// Load the Spritebatch Shader
		SpriteBatch::LoadShaders(m_lpShaders);

		return true;
	}

	void GraphicsManager::Draw()
	{
		m_lpSpriteBatch->Begin();

		Engine::States->Draw(m_lpSpriteBatch);

		m_lpSpriteBatch->End(m_lpGraphicsDevice, m_lpGraphicsMutex);
	}
}